package com.ly.mp.busicen.rule.log;

import java.time.Duration;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ly.mp.busicen.rule.log.RuleLogData.RuleLogType;

public class RuleLogPublisher {

	static Logger log = LoggerFactory.getLogger(RuleLogPublisher.class);

	LinkedList<RuleLogData> logs = new LinkedList<RuleLogData>();

	public static List<IRuleLogRecord> records = new ArrayList<IRuleLogRecord>();

	static String type(RuleLogType type) {
		String tp;
		switch (type) {
		case FLOW:
			tp = "X";
			break;
		case ACTION:
			tp = "A";
			break;
		case FILTER:
			tp = "F";
			break;
		case RULE:
			tp = "R";
			break;
		default:
			tp = "N";
			break;
		}
		return tp;
	}
	static String state(RuleLogState state) {
		String st;
		switch (state) {
		case START:
			st = "S";
			break;
		case BREAK:
			st = "B";
			break;
		case EXCPT:
			st = "E";
			break;
		case END:
			st = "F";
			break;
		default:
			st = "○";
			break;
		}
		return st;
	}
	
	static String endState(RuleLogState state) {
		String st;
		switch (state) {
		case START:
			st = "△△";
			break;
		case BREAK:
			st = "▼▲";
			break;
		case EXCPT:
			st = "▲▲";
			break;
		case END:
			st = "▼▼";
			break;
		default:
			st = "○○";
			break;
		}
		return st;
	}
	

	static {
		records.add((lg, lgs) -> {
			String logging;
			long timespan=0;
			if (!lgs.isEmpty()) {
				Duration duration = Duration.between(lgs.getLast().getTime(), lg.getTime());
				timespan = duration.toMillis();
			}
			logging = String.format("[%s%s][%-32s][%-20s][%-20s][%-10s]",type(lg.getType()),state(lg.getRunState()), lg.getRid(), lg.getFlow(),
					 lg.getName(), timespan);
			
			log.debug(logging);
			if (lg.getType() == RuleLogType.FLOW && lg.getRunState() != RuleLogState.START) {
				RuleLogData startLog = lgs.stream()
						.filter(m -> m.getType() == RuleLogType.FLOW && m.getRunState() == RuleLogState.START)
						.findFirst().get();
				Duration duration = Duration.between(startLog.getTime(), lg.getTime());
				String logStr = String.format("[%s][%-32s][%-20s][%s->%s][%s]",endState(lg.getRunState()), lg.getRid(), lg.getFlow(),
						startLog.getTime().format(DateTimeFormatter.ofPattern("yyyyMMdd hhmmss")),
						lg.getTime().format(DateTimeFormatter.ofPattern("yyyyMMdd hhmmss")), duration.toMillis());
				log.debug(logStr);
			}
		});
	}

	public void log(RuleLogData log) {		
		if (records != null && !records.isEmpty()) {
			records.forEach(m -> {
				m.loged(log, logs);
			});
		}
		logs.add(log);
	}

}
